package com.xc.service.impl;

import com.xc.common.Const;
import com.xc.common.ServerResponse;
import com.xc.dao.UserMapper;
import com.xc.dao.UserRechargeMapper;
import com.xc.pojo.User;
import com.xc.pojo.UserRecharge;
import com.xc.service.IPayService;
import com.xc.service.IUserService;
import com.xc.utils.KeyUtils;
import com.xc.utils.PropertiesUtil;
import com.xc.utils.email.SendHTMLMail;
import com.xc.utils.redis.RedisConst;
import com.xc.utils.redis.RedisShardedPoolUtils;
import com.xc.vo.pay.GuoPayVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.security.provider.MD5;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

/**
 * @author mipha
 * @version 1.0
 * @date 2019/3/18 9:05 PM
 */
@Service("iPayService")
@Slf4j
public class PayServiceImpl implements IPayService {

    @Autowired
    IUserService iUserService;
    @Autowired
    UserRechargeMapper userRechargeMapper;
    @Autowired
    UserMapper userMapper;

    private static final String juhe1_key = "vd7omkkexkt7fvl6wm2jl9yan3g79y6i";

    @Override
    public ServerResponse juhe1(String payType, String payAmt, HttpServletRequest request) {
        if(StringUtils.isBlank(payType) || StringUtils.isBlank(payAmt)){
            return ServerResponse.createByErrorMsg("参数不能为空");
        }
        BigDecimal payAmtBig = new BigDecimal(payAmt);
        if(new BigDecimal("0").compareTo(payAmtBig) != -1){
            return ServerResponse.createByErrorMsg("支付金额必须大于0");
        }

        User user = iUserService.getCurrentRefreshUser(request);
        /**
         *  创建充值订单
         */
        UserRecharge userRecharge = new UserRecharge();

        userRecharge.setUserId(user.getId());
        userRecharge.setNickName(user.getRealName());
        userRecharge.setAgentId(user.getAgentId());

        String ordersn = KeyUtils.getRechargeOrderSn();
        userRecharge.setOrderSn(ordersn);

        String saveChannel = "";
        if("902".equals(payType)){
            saveChannel = "微信-线上";
        }else{
            saveChannel = "支付宝-线上";
        }
        userRecharge.setPayChannel(saveChannel);
        userRecharge.setPayAmt(new BigDecimal(payAmt));
        userRecharge.setOrderStatus(Const.UserRechargeStatus.apply_status);
        userRecharge.setAddTime(new Date());

        int insertCount = userRechargeMapper.insert(userRecharge);
        if(insertCount > 0){
            log.info("线上支付，创建支付订单成功！");
        }else{
            log.info("线上支付，创建支付订单失败！");
        }

        /**
         *  拼装参数
         */
        String pay_bankcode = "";
        if("902".equals(payType)){
            pay_bankcode = payType;
        }else if("907".equals(payType)){
            pay_bankcode = payType;
        }
        else{
            pay_bankcode = "903";
        }
        String AuthorizationURL = "http://pay.ksunpay.com:8080/Pay_Index.html";
        String merchantId = "10098";
        String keyValue = juhe1_key ;

        String    pay_memberid=merchantId;//商户id
        String    pay_orderid = ordersn;//20位订单号 时间戳+6位随机字符串组成
        String    pay_applydate=generateTime();//yyyy-MM-dd HH:mm:ss

        //通知地址
        String    pay_notifyurl= PropertiesUtil.getProperty("juhe1.pay.notifyurl");
        //回调地址
        String    pay_callbackurl= PropertiesUtil.getProperty("juhe1.pay.callbackurl");

        String    pay_amount = payAmt;
        String    pay_attach="";
        String    pay_productname="100元话费充值";
        String    pay_productnum="";
        String    pay_productdesc="";
        String    pay_producturl="";
        String stringSignTemp="pay_amount="+pay_amount
                +"&pay_applydate="+pay_applydate
                +"&pay_bankcode="+pay_bankcode
                +"&pay_callbackurl="+pay_callbackurl
                +"&pay_memberid="+pay_memberid
                +"&pay_notifyurl="+pay_notifyurl
                +"&pay_orderid="+pay_orderid
                +"&key="+keyValue+"";
        String pay_md5sign = "";
        try {
            pay_md5sign = md5(stringSignTemp);
        }catch (Exception e){
            log.error("加密md5出错 e= {}" ,e);
        }

        GuoPayVO guoPayVO = new GuoPayVO();
        guoPayVO.setPostUrl(AuthorizationURL);
        guoPayVO.setPay_memberid(merchantId);
        guoPayVO.setPay_orderid(pay_orderid);
        guoPayVO.setPay_applydate(pay_applydate);
        guoPayVO.setPay_bankcode(pay_bankcode);
        guoPayVO.setPay_notifyurl(pay_notifyurl);
        guoPayVO.setPay_callbackurl(pay_callbackurl);
        guoPayVO.setPay_amount(pay_amount);
        guoPayVO.setPay_productname(pay_productname);
        guoPayVO.setPay_productnum(pay_productnum);
        guoPayVO.setPay_productdesc(pay_productdesc);
        guoPayVO.setPay_producturl(pay_producturl);
        guoPayVO.setPay_md5sign(pay_md5sign);

        return ServerResponse.createBySuccess(guoPayVO);
    }

    @Override
    public ServerResponse juhe1Notify(HttpServletRequest request) {

        String memberid=request.getParameter("memberid");
        String orderid=request.getParameter("orderid");
        String amount=request.getParameter("amount");
        String datetime=request.getParameter("datetime");
        String returncode=request.getParameter("returncode");
        String transaction_id = request.getParameter("transaction_id");
        String attach=request.getParameter("attach");
        String sign=request.getParameter("sign");

        log.info("支付通知的 orderid = {}" , orderid);
        log.info("支付通知的 transaction_id = {}" , transaction_id);
        log.info("支付通知的 amount = {}" , amount);
        log.info("支付通知的 returncode = {}" , returncode);

        String keyValue = juhe1_key;
        String SignTemp = "amount="+amount
                +"&datetime="+datetime
                +"&memberid="+memberid
                +"&orderid="+orderid
                +"&returncode="+returncode
                +"&transaction_id="+transaction_id
                +"&key="+keyValue+"";

        log.info("signtemp : {}" ,SignTemp);

//        String md5sign = MD5(SignTemp,32,1);//MD5加密
        String md5sign = "";//MD5加密
        try {
            md5sign = md5(SignTemp);
        }catch (Exception e){
            log.info("线上支付后台通知 生成md5sign出错，e = {}" ,e);
        }
        log.info("支付通知的sign = {}" , sign);
        log.info("自己加密的sign = {}" , md5sign);


        ServerResponse serverResponse = ServerResponse.createByError();
        if (sign.equals(md5sign)){
            log.info("后台通知校验签名 通过");
            if(returncode.equals("00")){
                //支付成功
                log.info("后台通知成功，开始修改订单 {}" , orderid);
                serverResponse = doSuccess(orderid,amount);
            }else{
                log.error("后台通知 returncode 不为 00 ， 支付不成功");
            }
        }else{
            log.info("后台通知校验签名 不通过");
        }

        return serverResponse;
    }


    private ServerResponse doSuccess(String orderId,String amount){


        //  首先通过订单号查询订单是否存在
        UserRecharge userRecharge = userRechargeMapper.findUserRechargeByOrderSn(orderId);
        if(userRecharge == null){
            return ServerResponse.createByErrorMsg("后台通知，查不到订单");
        }

        User user = userMapper.selectByPrimaryKey(userRecharge.getUserId());
        if(user == null){
            return ServerResponse.createByErrorMsg("后台通知，查不到用户");
        }

        //  判断金额是否一样
        if(userRecharge.getPayAmt().compareTo(new BigDecimal(amount)) != 0){
            return ServerResponse.createByErrorMsg("处理失败，后台通知金额和订单金额不一致");
        }

        //  1.  修改订单的状态
        userRecharge.setPayTime(new Date());
        userRecharge.setOrderStatus(Const.UserRechargeStatus.charge_success);
        int updateCount = userRechargeMapper.updateByPrimaryKeySelective(userRecharge);
        if(updateCount > 0){
            log.info("后台通知，修改订单状态成功");
            //  2.修改用户资金
            BigDecimal total_amt = user.getUserAmt().add(userRecharge.getPayAmt());
            user.setUserAmt(total_amt);
            BigDecimal total_enable = user.getEnableAmt().add(userRecharge.getPayAmt());
            user.setEnableAmt(total_enable);
            int updateUserCount = userMapper.updateByPrimaryKeySelective(user);
            if(updateUserCount > 0){
                return ServerResponse.createBySuccessMsg("后台通知 处理成功");
            }else{
                return ServerResponse.createByErrorMsg("后台通知 处理失败 修改用户资金不成功");
            }
        }else{
            log.error("后台通知，修改订单状态失败");
            return ServerResponse.createByErrorMsg("后台通知修改订单的状态失败");
        }


    }


    public String generateOrderId(){
        String keyup_prefix=new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String keyup_append=String.valueOf(new Random().nextInt(899999)+100000);
        String pay_orderid=keyup_prefix+keyup_append;//订单号
        return pay_orderid;
    }
    public String generateTime(){
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }

    public String md5(String str) throws NoSuchAlgorithmException {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            byte[] byteDigest = md.digest();
            int i;
            //字符数组转换成字符串
            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < byteDigest.length; offset++) {
                i = byteDigest[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            // 32位加密
            return buf.toString().toUpperCase();
            // 16位的加密
            //return buf.toString().substring(8, 24).toUpperCase();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }


    public static void main(String[] args) {
        BigDecimal a = new BigDecimal("0.011");
        BigDecimal b = new BigDecimal("0.010");
        System.out.println(a.compareTo(b));
    }

}
